"""
页面状态管理服务
"""
from datetime import datetime
from typing import List, Optional
from axiom_boot.di import service, autowired
from axiom_boot.logging.setup import get_logger
from axiom_boot.database.base_service import BaseService
from axiom_boot.database import transactional

from ..mapper.scraper_page_status_mapper import ScraperPageStatusMapper
from ..models.scraper_page_status import ScraperPageStatus

logger = get_logger(__name__)


@service()
class PageStatusService(BaseService[ScraperPageStatus, ScraperPageStatusMapper]):
    """页面状态管理服务"""
    
    def __init__(self, mapper: ScraperPageStatusMapper = autowired()):
        super().__init__(mapper)
    
    @transactional
    async def mark_page_started(self, site_name: str, page_number: int, per_page: int, task_id: str) -> ScraperPageStatus:
        """标记页面开始处理"""
        try:
            # 查找或创建页面状态
            page_status = await self.find_by_site_and_page(site_name, page_number, per_page)
            logger.debug(f"查询结果: page_status = {page_status}")
            
            if page_status:
                logger.debug(f"找到现有页面状态: ID={page_status.id}, status={page_status.status}")
                # 更新现有记录
                await self.update_by_pk(page_status.id, {
                    "status": "processing",
                    "task_id": task_id,
                    "started_at": datetime.now(),
                    "retry_count": page_status.retry_count + 1
                })
                # 更新本地对象状态
                page_status.status = "processing"
                page_status.task_id = task_id
                page_status.retry_count = page_status.retry_count + 1
            else:
                logger.debug("未找到页面状态，创建新记录")
                # 创建新记录
                page_status = ScraperPageStatus(
                    site_name=site_name,
                    page_number=page_number,
                    per_page=per_page,
                    status="processing",
                    task_id=task_id,
                    started_at=datetime.now(),
                    retry_count=1
                )
                logger.debug(f"创建新对象: {page_status}, ID: {getattr(page_status, 'id', 'None')}")
                saved_model = await self.save(page_status)
                logger.debug(f"保存后的对象: {saved_model}, ID: {saved_model.id}")
                page_status = saved_model
            
            logger.debug(f"页面{page_number}标记为处理中")
            return page_status
            
        except Exception as e:
            logger.error(f"标记页面{page_number}开始失败: {e}")
            raise
    
    @transactional
    async def mark_page_completed(self, site_name: str, page_number: int, per_page: int, scraped_count: int, expected_count: int = 0):
        """标记页面完成"""
        try:
            page_status = await self.find_by_site_and_page(site_name, page_number, per_page)
            
            if page_status:
                await self.update_by_pk(page_status.id, {
                    "status": "completed",
                    "scraped_count": scraped_count,
                    "expected_count": expected_count or scraped_count,
                    "completed_at": datetime.now(),
                    "last_error": None
                })
                
                logger.info(f"页面{page_number}标记为完成，爬取{scraped_count}辆")
            
        except Exception as e:
            logger.error(f"标记页面{page_number}完成失败: {e}")
    
    @transactional
    async def mark_page_failed(self, site_name: str, page_number: int, per_page: int, error_msg: str):
        """标记页面失败"""
        try:
            page_status = await self.find_by_site_and_page(site_name, page_number, per_page)
            
            if page_status:
                await self.update_by_pk(page_status.id, {
                    "status": "failed",
                    "last_error": error_msg[:500]  # 限制错误信息长度
                })
                
                logger.warning(f"页面{page_number}标记为失败: {error_msg[:100]}")
            
        except Exception as e:
            logger.error(f"标记页面{page_number}失败状态失败: {e}")
    
    async def is_page_completed(self, site_name: str, page_number: int, per_page: int) -> bool:
        """检查页面是否已完成"""
        page_status = await self.find_by_site_and_page(site_name, page_number, per_page)
        return page_status and page_status.status == "completed"
    
    async def should_retry_page(self, site_name: str, page_number: int, per_page: int, max_retry: int = 3) -> bool:
        """检查页面是否需要重试"""
        page_status = await self.find_by_site_and_page(site_name, page_number, per_page)
        
        if not page_status:
            return True  # 从未处理过，需要处理
        
        if page_status.status == "completed":
            return False  # 已完成，不需要重试
        
        if page_status.status == "failed" and page_status.retry_count < max_retry:
            return True  # 失败但未达到最大重试次数
        
        if page_status.status == "pending":
            return True  # 待处理
        
        return False  # 其他情况不重试
    
    async def get_pages_to_process(self, site_name: str, total_pages: int, per_page: int, max_retry: int = 3) -> List[int]:
        """获取需要处理的页面列表（断点续传核心逻辑）"""
        try:
            # 获取所有需要重试的失败页面
            failed_pages = await self.find_failed_pages(site_name, max_retry)
            retry_page_numbers = [p.page_number for p in failed_pages]
            
            # 获取已完成的页面
            completed_pages = await self.find_completed_pages(site_name)
            completed_page_numbers = set(p.page_number for p in completed_pages)
            
            # 计算需要处理的页面
            pages_to_process = []
            
            # 添加重试页面
            pages_to_process.extend(retry_page_numbers)
            
            # 添加从未处理过的页面
            for page_num in range(1, total_pages + 1):
                if page_num not in completed_page_numbers and page_num not in retry_page_numbers:
                    pages_to_process.append(page_num)
            
            pages_to_process.sort()
            
            logger.info(f"{site_name}: 总{total_pages}页，已完成{len(completed_page_numbers)}页，需处理{len(pages_to_process)}页")
            if retry_page_numbers:
                logger.info(f"重试页面: {retry_page_numbers}")
            
            return pages_to_process
            
        except Exception as e:
            logger.error(f"获取待处理页面失败: {e}")
            # 失败时返回全部页面
            return list(range(1, total_pages + 1))
    
    async def get_site_progress(self, site_name: str) -> dict:
        """获取站点进度统计"""
        try:
            stats = await self.get_site_stats(site_name)
            
            total_pages = sum(stats[status] for status in ["pending", "processing", "completed", "failed"])
            completed_pages = stats["completed"]
            
            progress = {
                "total_pages": total_pages,
                "completed_pages": completed_pages,
                "failed_pages": stats["failed"],
                "pending_pages": stats["pending"],
                "processing_pages": stats["processing"],
                "total_scraped": stats["total_scraped"],
                "completion_rate": f"{(completed_pages / max(total_pages, 1) * 100):.1f}%" if total_pages > 0 else "0%"
            }
            
            return progress
            
        except Exception as e:
            logger.error(f"获取站点进度失败: {e}")
            return {"error": str(e)}
